Technical Note TN2046
AEStream and Friends

目次

このテクニカルノートは、ストリーム指向の呼び出し規則を使ってアップルイベントレコードとアップルイベントディスクリプタを作成するのに使用できる AEStream* の API コレクションについて説明します。これらの API により、興味深く維持が簡単なストリーム指向のアルゴリズムを使って、複雑なアップルイベントディスクリプタレコードを作成できます。

AEStream* ルーチンは、Apple Event Manager API のほかのルーチンに代わるものとして意図されたものではありません。むしろ、Apple Event Manager の API を強化するものであり、さまざまなプログラミング方式に対応します。AEStream* ルーチンを Apple Event Manager の API コレクションと組み合わせて使えば、より広範な種類のアルゴリズムで、もっと簡単にアップルイベントディスクリプタレコードを作成できるようになります。

このテクニカルノートは、ストリーム指向のアルゴリズムを使って複雑なアップルイベントディスクリプタを作成することに興味があるアプリケーション開発者に向けて書かれています。

[2002 年 3 月 29 日]






はじめに

AEStream* ルーチンにより、ファイルを開いてデータを書き込むのと同じように、アップルイベントディスクリプタレコードにデータを追加できます。AEStreamRef が開いたら、呼び出し側は、作成するディスクリプタを記述する AEStream* のルーチンを使って、このストリームに情報を追加できます。このストリームに送られたコマンドは、AEStreamRef に保存されますが、 ディスクリプタレコードを作成するために実際に統合されるのは、AEStreamRef が閉じられた後です。



リスト 1 単純なディスクリプタの作成方法を示す例

    AEStreamRef ref;
    char* p = "Hello World";

        /* ストリームを開く */
    ref = AEStreamOpen();
    if (ref != NULL) {

            /* ディスクリプタをストリームに保存する */
        err = AEStreamWriteDesc( ref, typeChar, p, strlen(p));
        if (err == noErr) {

                /* ストリームを閉じて、内容を新しいディスクリプタ、theNewDescに集める*/
            AEDesc theNewDesc;
            err = AEStreamClose( ref, &theNewDesc);
            if (err == noErr) {

                /* ここで、新しいディスクリプタを何かの目的で使用する  */

                    /* ディスクリプタを使い終わったら廃棄する*/
                AEDisposeDesc(&theNewDesc);
            }
        } else {
                /* ディスクリプタの作成中にエラーが発生した場合は、
                ストリームを閉じて結果を破棄する*/
            AEStreamClose( ref, fNULL);
        }
    }



最も単純な場合では、リスト 1 に示すように AEStreamRef を使って簡単なディスクリプタレコードを作成できます。しかし、この例では、リスト 2 に示す AECreateDesc への簡単な呼び出しよりも AEStream* を呼び出す方が利点があるということが明白ではありません。またこの例の場合、AEStream* 呼び出しを使うことにこれといった利点がないことは確かです。しかしほかの似たような状況でも、単に AECreateDesc を呼び出すよりも、AEStream* を呼び出す方が良い選択である場合もあります。



リスト 2 AECreateDesc を使った単純なディスクリプタの作成方法を示す例

    char* p = "Hello World";
    err = AECreateDesc(typeChar, p, strlen(p), &textDesc);


たとえば、ディスクリプタレコードの内容が複雑で、内容のすべてを一度には決定できないけれども、ディスクリプタレコードの内容としてデータを順々に蓄積していきたいとします。AECreateDesc を使ってこのようなディスクリプタを作成する場合は、データを自分で蓄積し、大きな連続したメモリブロックに集め、その後 AECreateDesc を呼び出してデータをディスクリプタにコピーする必要があります。しかし、AEStream* ルーチンは、余分な管理情報を維持しなくてもこれらの操作の実行を可能にする機能を提供します。リスト 3 で示すように、繰り返し AEStreamWriteData ルーチンを呼び出すことによって、ディスクリプタレコードの内容を蓄積できます。また、AEStreamWriteData の呼び出し時に、ディスクリプタに含めるすべての情報を一度に指定する必要もありません(たとえば、多数の異なるルーチンで、複数の呼び出しにまたがって蓄積することができます)。



リスト 3  1 度に 1 文字ずつ蓄積して単純なディスクリプタを構築する方法を示す例

    /* AddTextDesc は、theText が指す文字列の
   テキストを含むテキストディスクリプタを AEStreamRef に追加する。
   テキストは 1 度に 1 文字ずつ追加する。
   以下、AEStream* ルーチンを使って、ディスクリプタのデータ内容を
   インクリメンタルに積み上げていく方法を示す */
OSStatus AddTextDesc(AEStreamRef ref, char* theText) {
    char* p;
    OSStatus err;

        /* テキストタイプのディスクリプタを開始 */
    err = AEStreamOpenDesc( ref, typeChar);
    if (err == noErr) {

            /* 文字列を 1 度に 1 文字ずつ
           ディスクリプタに追加 */
        for (p=theText; *p; p++) {

                /* 1 文字を書き出す */
            err = AEStreamWriteData( ref, p, 1);
            if (err != noErr) break;
        }
        if (err == noErr) {

                /* ディスクリプタの終了を表す */
            err = AEStreamCloseDesc(AEStreamRef ref);
        }
    }
    return err;
}

....

    AEStreamRef ref;
    ref = AEStreamOpen();
    if (ref != NULL) {

            /* AddTextDesc を呼び出し、テキストディスクリプタを AEStreamRef に追加する */
        err = AddTextDesc(ref, "Hello World");
        if (err == noErr) {
            AEDesc theNewDesc;

                /* ストリームを閉じて、内容を新しいディスクリプタ、theNewDesc に集める */
            err = AEStreamClose( ref, &theNewDesc);
            if (err == noErr) {

                /* ここで、新しいディスクリプタを何かの目的で使用する  */

                    /* ディスクリプタを使い終わったらディスクリプタを廃棄する  */
                AEDisposeDesc(&theNewDesc);
            }
        } else {
                /* ディスクリプタの作成中にエラーが発生した場合は、
                ストリームを閉じて結果を破棄する */
            AEStreamClose( ref, NULL);
        }
    }



アルゴリズムの実装によっては、リスト 3 の手法を使ってディスクリプタレコードをインクリメンタルに構築していく方がより理にかなっていることがあります。同じように、AEStream* ルーチンを使って、AEDescList 構造体と AERecord 構造体をインクリメンタルに構築することもできます。たとえば、AEDescList リストを作成するためには、個々のディスクリプタを記述する呼び出しのシーケンスを、AEStreamOpenListAEStreamCloseList への呼び出しで囲みます。 リスト 4 で定義されている AddAListOfStrings ルーチンは、これらのルーチンを使って単純なテキストディスクリプタリストを作成する方法の例を示します。また予想されるように、AEStreamOpenListAEStreamCloseList への呼び出しをネストして、リストの中にリストをまったく問題なく作成できます。



リスト 4 文字列のリストを含む複雑なディスクリプタの作成方法を示す例

    /* AddAListOfStrings は、strings パラメータに渡される文字列ポインタの配列
    を使って構築された n 個の typeChar ディスクリプタのリストを含む 1 つの 
    AEDescList 構造体を、AEStreamRef に追加する */
OSStatus AddAListOfStrings(AEStreamRef ref, char** strings, long n) {
    OSStatus err;
    long i;

            /* リストへの項目の蓄積を開始 */
    err = AEStreamOpenList(ref);
    if (err == noErr) {

            /* リスト 3 で定義された AddTextDesc ルーチンを使って
            すべての文字列をリストに追加
            */
        for (i=0; i<n; i++) {
            err = AddTextDesc(ref, strings[i]);
            if (err != noErr) break;
        }

            /* リストを閉じる */
        if (err == noErr) {
            err = AEStreamCloseList(ref);
        }
    }
    return err;
}

        /* ディスクリプタのリストを作成するために使用する文字列のリスト*/
    char* gStringList[] = {
        "Hello World",
        "Apple events",
        "AEStream*",
        "one last string"
    };

    AEStreamRef ref;
    long i;
    OSStatus err;

        /* ストリームを開く */
    ref = AEStreamOpen();
    if (ref != NULL) {

            /* 文字列のリストを含むディスクリプタを AEStream に追加 */
        err = AddAListOfStrings(ref, gStringList,
                           sizeof(gStringList)/sizeof(char*));

            /* エラーがない場合は、
            AEStream を閉じて、新しいディスクリプタを保存する */
        if (err == noErr) {
            AEDesc theNewDesc;

                /* ストリームを閉じて、内容を新しいディスクリプタ、theNewDesc に集める */
            err = AEStreamClose( ref, &theNewDesc);
            if (err == noErr) {

                /* ここで、何かの目的で新しいディスクリプタを使用する   */

                    /* ディスクリプタを使い終わったらディスクリプタを廃棄する */
                AEDisposeDesc(&theNewDesc);
            }
        } else {
                /* ディスクリプタの作成中にエラーが発生した場合は、
                ストリームを閉じて結果を破棄する*/
            AEStreamClose( ref, NULL);
        }
    }



同様の手法を使って、複雑な AERecord を構築し、アップルイベントレコードにパラメータを追加することができます。ほとんどの場合、レコードへのディスクリプタの追加、アップルイベントへのパラメータの追加は、AEDescList の作成と同じように行えます。 しかし、AEStream* ルーチンには、レコード中のディスクリプタに対応させるレコードのタイプとキーワードを指定できる追加の機能があります。レコード作成およびレコードへの要素の追加のためのルーチンは、本文書の後半で示します。

先頭に戻る



AEStream* に関する注意事項

次に、AEStream* ルーチンを使用する際に、忘れてはならないいくつかの重要事項を示します。

  • AEStreamOpenAEStreamClose への呼び出しの間に作成するディスクリプタは 1 つだけです。 AEStreamOpenAEStreamClose の呼び出しの間で 2 つ以上のディスクリプタを記述したときに、AEStream* が、リストを自動的に作成してくれることを期待してはいけません。リストを作成したい場合は、 AEStreamOpenListAEStreamCloseList の呼び出し間に複数のディスクリプタを追加します。

  • どの呼び出しにも対応する呼び出しを配置するように注意します。AEStreamOpenDesc への各呼び出しには AEStreamCloseDesc への呼び出しが必要で、 AEStreamOpenList の各呼び出しには対応する AEStreamCloseList の呼び出しが必要という具合にする必要があります。リスト 5 の概略で示すように、 AEStream* ルーチンの複合的な呼び出しシーケンスを作成すれば、複雑なネスト構造を作成できます。

    リスト 5 AEStream* への呼び出しをネストし複雑なアップルイベントディスクリプタを作成する方法を示す呼び出しシーケンスの概略

    ストリームを開く
       リストを開始する
          ディスクリプタの書き出し
          ディスクリプタの書き出し
          ディスクリプタを開く
             データの書き出し
             データの書き出し
             データの書き出し
             データの書き出し
          ディスクリプタを閉じる
          レコードを開く
             レコードタイプの設定
             キー/ディスクリプタのペアの書き出し
             キー/ディスクリプタのペアの書き出し
          レコードを閉じる
          リストを開始する
             ディスクリプタの書き出し
             ディスクリプタの書き出し
             レコードを開く
                レコードのタイプの書き出し
                キー/ディスクリプタのペアの書き出し
                キー/ディスクリプタのペアの書き出し
             レコードを閉じる
          リストを終了する
          ディスクリプタの書き出し
       リストを終了する
    ストリームを閉じる -> 新しいディスクリプタ
    


    The AEStream* ルーチンは、自身のライブラリに対して行われた呼び出しのネストの状態を追跡する状態情報を保持します。この情報は、自身の操作に必要ですが、エラーの報告にもこの情報を使います。ライブラリへの呼び出しにおいて対応が取れていない場合は、AEStreamRef を閉じようとしたときに、AEStreamCloseerrAEStreamBadNesting エラーを返します。

  • その他の代替方法との比較検討を行います。AEStream* ルーチンの代わりに、AECreateDesc ルーチンまたは AEBuild* ルーチン(テクニカルノート TN2045 を参照)などの本来の Apple Event Manager ルーチンを使った方が、コードは、単純で、明快で、保守しやすくなるかどうかを考えてみます。AEStream* を使った方がより明快になる実装もありますが、実装によっては、AEStream* がベストの選択ではないかもしれません。

  • AEStreamClose によって作成されたディスクリプタレコードは必ず破棄します。 使い終わった AEDesc レコードを破棄するのはアプリケーションの役目です。

先頭に戻る



アップルイベントストリームの開閉

AEStreamClose の呼び出し時に新しいディスクリプタレコードの作成に使用されるコマンドを蓄積するための、新しい AEStreamRef を作成して開くことを可能にする 3 つのルーチンがあります。 AEDescAEDescList、および AERecord の各タイプのレコードを作成するためには、AEStreamOpen を使用する必要があります。AEStreamCreateEvent ルーチンを使えば、新しい AppleEvent レコードを作成でき、AEStreamOpenEvent を使えば、既存の AppleEvent レコードを開いてパラメータを追加できます。AEStreamRef を開くのにどのルーチンを使ったとしても、ストリームを閉じて、AEStreamRef に対して発行されたすべてのコマンドを、結果のディスクリプタレコードに蓄積するには AEStreamClose を呼び出す必要があります。

AEStreamOpen



AEStreamRef AEStreamOpen(void);

結果:
1 つの AEStreamRef。エラーが発生した場合は、値 NULL



AEStreamOpen は、アップルイベントディスクリプタレコードを記述するコマンドの蓄積のために使用できる新しい AEStreamRef を開きます。 1 つの AEStreamRef を開いた後で、ほかの AEStream* ルーチンを呼び出せば、作成するディスクリプタレコードの形式を記述できます。リスト 1 の例は、このルーチンの呼び出し方法を示します。

先頭に戻る



AEStreamClose



OSStatus AEStreamClose(
    AEStreamRef ref,
    AEDesc* desc);

パラメータ

  • ref - AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent のいずれかで作成された AEStreamRef

  • desc - AEStreamRef に書き込まれた項目の並びの保存場所である AEDesc レコードへのポインタ、または値 NULL。このパラメータを NULL に設定した場合、AEStreamClose は結果を破棄し、AEStreamRef もその状態に関わらず破棄します。

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しが成功したことを意味します。



AEStreamClose は、AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent の 1 つを呼び出すことによって作成された AEStreamRef を閉じて、割り当てを解除します。2 番目のパラメータにディスクリプタへのポインタが渡されている場合は、作成されたディスクリプタレコードはそのディスクリプタに保存されます。AEStreamRef が、AEStreamOpenEvent または AEStreamCreateEvent により作成された場合は、作成されたディスクリプタには、完全なアップルイベントが含まれます。



注意:
AEStreamClose によって返されるディスクリプタレコードを破棄するのは呼び出し側のアプリケーションの役目です。ディスクリプタレコードの使用後は、AEDisposeDesc を呼び出して破棄する必要があります。



desc パラメータに NULL を渡すと、 AEStreamClose に、結果を破棄し、AEStreamRef をその状態に関わらず処分するように指示できます。この形で AEStreamClose を呼び出した時には、ネストされた AEStream* への呼び出し間の対応(AEStreamOpenListAEStreamCloseList など)について心配する必要がありません。 これは、AEStreamRef を破棄したいけれども、状態が必ずしもはっきりしていないエラー処理などの場合に役立ちます。

ネストされた呼び出しシーケンスはすべて、AEStreamClose を呼び出す前に、正しく対応させておく必要があります。つまり、すべての AEStreamOpenList の呼び出しには、対応する AEStreamCloseList の呼び出しが必要です。すべての AEStreamOpenRecord の呼び出しには、対応する AEStreamCloseRecord の呼び出しが必要です。その他の場合も同様です。ネストされた呼び出しの中で正しく対応を取らないまま、AEStreamRef を閉じようとして AEStreamClose を呼び出すと、errAEStreamBadNesting エラーが生じます。リスト 1 の例は、AEStreamClose を呼び出して作成されたディスクリプタを取得する方法、およびエラー発生後に AEStreamClose を呼び出して結果を破棄する方法を示します。

AEStreamClose が失敗しエラーが返って来た場合、desc が指す AEDesc レコードは、 typeNull というディスクリプタに設定されます。このため、結果コードに関係なく、AEStreamClose により返されるディスクリプタレコードを対象に AEDisposeDesc を呼び出しても安全です。

先頭に戻る



ディスクリプタの書き出し

AEStream* ルーチンには、AEStreamRef への個別のディスクリプタレコードの追加を可能にする 3 つの異なる機能があります。

  1. AEStreamWriteAEDesc は、前もって構築した AEDesc レコード(形式は問わない)を AEStreamRef に書き出せるようにします。これにより、プログラムで定数を使うのとまったく同じ方法で、前もって構築したディスクリプタを使って複雑なディスクリプタ構造体を作り上げることができます。

  2. AEStreamWriteDesc は、ディスクリプタを作成するのに使用されるデータバッファと typeCode の指定を可能にします。

  3. AEStreamOpenDesc の呼び出し、AEStreamWriteData の呼び出し、 AEStreamCloseDesc の呼び出しは、データのインクリメンタルな追加によるディスクリプタレコードの作成を可能にします。AEStreamWriteData への複数の呼び出しにまたがって提供されたデータはすべて、ディスクリプタレコードが作成されるときに統合されます。 リスト 3 の例は、これら 3 つの呼び出しを使ってディスクリプタレコードを構築する方法を示します。

この節ではこれらの 3 つのルーチンについて説明します。 3 つのルーチンはすべて、個別のディスクリプタレコード (AEDesc レコード)を作成するために使えるということは頭に入れておいてください。また、これらのルーチンは、ディスクリプタレコードを AEDescList 構造体 または AERecord 構造体に追加するために使われますが、そのためには、ルーチンをそれぞれ AEStreamOpenListAEStreamCloseList または AEStreamOpenRecordAEStreamCloseRecord の呼び出しで囲む必要があります。

AEStreamWriteAEDesc



OSStatus AEStreamWriteAEDesc(
    AEStreamRef ref,
    const AEDesc *desc);

パラメータ:

  • ref - AEStreamOpenAEStreamCreateEvent、またはAEStreamOpenEvent のいずれかにより作成された AEStreamRef

  • desc - AEStreamRef にコピーすべき AEDesc レコードへのポインタ。 AEStreamWriteAEDesc の呼び出し後、ストレージを保持しておく必要がないように、AEStreamWriteAEDesc は、すぐに AEDesc をコピーします。

結果
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamWriteAEDesc は、既存のアップルイベントディスクリプタレコード全体を AEStreamRef にコピーします。

作成中のディスクリプタに追加したい構築済みのディスクリプタレコードがある場合に、このルーチンは有効です。たとえば、ディスクリプタを構築するたびに作成するとコストがかかる複雑なオブジェクト指定子レコードがあり、それを多数の様々なディスクリプタレコードに追加したいとします。この場合、プログラムの起動時にこのオブジェクト指定子レコードを作成し、その後定数と同じように何度も、AEStreamWriteAEDesc への呼び出しの中で使えば効率的です。

先頭に戻る



AEStreamWriteDesc



OSStatus AEStreamWriteDesc(
    AEStreamRef ref,
    DescType newType,
    const void* data,
    Size length);

パラメータ:

  • ref - AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent のいずれかにより作成された AEStreamRef

  • newType - AEStreamRef にコピーされる新しい AEDesc のタイプコード。

  • data - length パラメータが指定するバイト数のデータを含むメモリブロックへのポインタ。このデータは、AEStreamRef にコピーされる新しい AEDesc の中で使用されます。AEStreamWriteDesc の呼び出し後、メモリを保持しておく必要がないように、AEStreamWriteDesc は、データをすぐにコピーします。

  • length - data パラメータが指すデータのバイト数。

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamWriteDesc は、ディスクリプタレコードの作成に使用される typeCode とデータバッファの指定を可能にします。このルーチンでは、ディスクリプタレコードに使うすべてのデータを一度に提供する必要があります。 データをインクリメンタルに追加する場合は、 AEStreamOpenDescAEStreamWriteData、およびAEStreamCloseDesc(以降で説明)の呼び出しを使う必要があります。

先頭に戻る



AEStreamOpenDesc



OSStatus AEStreamOpenDesc(
    AEStreamRef ref,
    DescType newType);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamOpenDesc の呼び出しは、0 回またはそれ以上の AEStreamWriteData への呼び出しシーケンスの開始を示します。AEStreamOpenDesc への呼び出しと AEStreamCloseDesc への呼び出しの間で行われる AEStreamWriteData の呼び出しはすべて、AEStreamOpenDesc への呼び出しで指定された typeCode を持つディスクリプタを作成するために統合されます。 AEStreamOpenDesc への呼び出しの後には、AEStreamWriteData に対する任意の数の呼び出しを続けることができ、最後には AEStreamCloseDesc への呼び出しで対応させる必要があります。

先頭に戻る



AEStreamWriteData



OSStatus AEStreamWriteData(
    AEStreamRef ref,
    const void* data,
    Size length);

パラメータ:

  • ref - AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent のいずれかにより作成された AEStreamRefAEStreamWriteData を呼び出す前に、AEStreamOpenDesc または AEStreamOpenKeyDesc を、この AEStreamRef を対象にして呼び出しておく必要があります。

  • data - length パラメータが指定するバイト数のデータを含むメモリブロックへのポインタ。このデータは、AEStreamRef にコピーされる新しい AEDesc の中で使用されます。 AEStreamWriteData の呼び出し後、メモリを保持しておく必要がないように、AEStreamWriteData は、データをすぐにコピーします。

  • length - data パラメータが指すバイト数。

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamWriteData は、AEStreamRef で定義されている現在のディスクリプタレコードへデータを追加します。このルーチンは、ディスクリプタレコードのデータ内容をインクリメンタルに追加するために何度でも呼び出せます。AEStreamWriteData への呼び出しの前には、AEStreamOpenDesc または AEStreamOpenKeyDesc への呼び出しがなければなりません。ディスクリプタレコードのデータ内容を定義するために AEStreamWriteData を 1 度以上呼び出した後には、ディスクリプタの定義を終了し、先行する AEStreamOpenDesc または AEStreamOpenKeyDesc の呼び出しに対応させるために、AEStreamCloseDesc を呼び出す必要があります。リスト 3 の例は、AEStreamWriteData の呼び出し方法を示します。

先頭に戻る



AEStreamCloseDesc



OSStatus AEStreamCloseDesc(AEStreamRef ref);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamCloseDesc は、AEStreamRef に書き込むディスクリプタレコードの定義の終了を示すのに使用されます。 ディスクリプタレコードのデータ内容を定義するために AEStreamWriteData を 1 度以上呼び出した後には、ディスクリプタの定義を終了し、先行する AEStreamOpenDesc または AEStreamOpenKeyDesc の呼び出しに対応させるために、このルーチンを呼び出す必要があります。 リスト 3 の例は、AEStreamCloseDesc の呼び出し方法を示します。

先頭に戻る



リストの書き出し

この節で説明するルーチンは、結果として作成されるディスクリプタへ AEDescList 構造体を追加するために結合される複数のディスクリプタレコード を区切るのに使用されます。

AEStreamOpenList



OSStatus AEStreamOpenList(AEStreamRefref);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、 呼び出しの成功を意味します。



AEStreamOpenList の呼び出しは、結果として作成されるディスクリ プタレコードに 1 つの AEDescList 構造体を作成するために結合される 0 個以上のディスクリプタ定義の並びの開始を示します。AEStreamOpenList への各呼び出しにはすべ て、AEStreamCloseList への呼び出しを対応させる必要があります。 AEDescList 構造体に含まれているディスクリプタは次のいずれかになります。

  1. ディスクリプタの書き出しの節で説明した 3 つのメソッドのいずれかを使って定義された AEDesc

  2. この節で説明したルーチンを使って定義された AEDescList

  3. レコードの書き出しの節で説明したルーチンを使って定 義された AERecord

先頭に戻る



AEStreamCloseList



OSStatus AEStreamCloseList(AEStreamRefref);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、 呼び出しの成功を意味します。



AEStreamCloseListAEStreamOpenList への呼び出しで開始された リストの終了を示すのに使われます。このルーチンは、 AEStreamRef にいくつかのディスクリプタを書き出した後に、先に行っ た AEStreamOpenList への呼び出 しに対応させるために使います。

先頭に戻る



レコードの書き出し

AERecord 構造体を書き出すために提供されているルーチンは、AEDescList を書き出すために提供されているルーチンと非常に似ています。主な違 いは、AERecord を書き出すルーチンには、AERecord のタイプコードの指定とレコードの要素に対応するキーワードの指定機 能が備わっていることです。自由度を高めるために AEStream* ルー チンには、これらの追加の要素を指定する方法が複数提供されています。

AEStreamOpenRecord



OSStatus AEStreamOpenRecord(
    AEStreamRef ref,
    DescType newType);

パラメータ:

  • ref - AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent のいずれかに より作成された AEStreamRef

  • newType - AEStreamRef にコピーされる新 しい AERecord のタイプコード。typeAERecord'reco')が使われることもありますが、通常はその他のタイプが使用されま す。

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、 呼び出しの成功を意味します。



AEStreamOpenRecord の呼び出しは、結果として作成されるディスク リプタレコードに 1 つの AERecord 構造体を作成するために後で結合される 0 個以上のキーワード/ディスクリプタの 定義の並びの開始を示します。すべての AEStreamOpenRecord への呼び出しは、 AEStreamCloseRecord への呼び出しで対応させる必要があります。各 キーワード/ディスクリプタの定義は、AEStreamWriteKeyDescAEStreamOpenKeyDesc、または AEStreamWriteKey への呼び出しに より始まります。

先頭に戻る



AEStreamCloseRecord



OSStatus AEStreamCloseRecord(AEStreamRefref);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、 呼び出しの成功を意味します。



AEStreamCloseRecord は、AEStreamOpenRecord への呼び出しにより 開始されたレコードの終了を示すのに使われます。このルーチンは、キーワード/ディスクリプタのペアを AEStreamRef に書き込んだ後、先に行われた AEStreamOpenRecord への呼び出 しに対応させるために呼び出します。

先頭に戻る



AEStreamSetRecordType



OSStatus AEStreamSetRecordType(
    AEStreamRef ref,
    DescTypenewType);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、 呼び出しの成功を意味します。



AEStreamOpenRecord の後に AEStreamSetRecordType を呼 び出すことによって、AEStreamOpenRecord の呼び出しの newType パラメータで指定されている AERecord のタイプを別のタイプに設定できます。コードの中でネストされたレコードを作成している場合、AEStreamSetRecordType は、最後に 行った AEStreamOpenRecord へ の呼び出しに対応する AERecord のタイプを設定します。このルーチンは、 AEStreamOpenRecordAEStreamCloseRecord の呼 び出しの間でのみ呼び出せます。

先頭に戻る



AEStreamWriteKeyDesc



OSStatus AEStreamWriteKeyDesc(
    AEStreamRef ref,
    AEKeyword key,
    DescType newType,
    const void* data,
    Size length);

パラメータ:

  • ref - AEStreamOpenAEStreamCreateEvent、または AEStreamOpenEvent のいずれかによって作成された AEStreamRefAEStreamOpenRecord/AEStreamCloseRecord の呼び出しはネストされている場合があるので、この呼び出しは、最後に行った AEStreamOpenRecord への呼び出しに対応する AERecord に新しい AEKeyword/AEDesc のペアを追加します。

  • key - 現在の AERecord にコピーされる新しい AEDesc に対応する AEKeyword

  • newType - AEStreamRef にコピーされる新しい AEDesc のタイプコード。

  • data - length パラメータが指定するバイト数のデータを含むメモリブロックへのポインタ。このデータは、AEStreamRef にコピーされる新しい AEDesc の中で使用されます。AEStreamWriteKeyDesc の呼び出し後、メモリを保持しておく必要がないように、AEStreamWriteKeyDesc は、データをすぐにコピーします。

  • length - data パラメータが指すデータのバイト数。

結果
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamWriteKeyDesc を呼び出して、AERecord に含める完全なキーワード/ディスクリプタのペアを AEStreamRef に書き出します。 このルーチンは、AEStreamOpenRecordAEStreamCloseRecord の呼び出しの間でのみ呼び出せます。 AEStreamWriteKeyDesc は、Apple Event Manager のルーチン、AEPutParamPtr と似ており、追加の AEKeyword パラメータを持っていることを除けばほとんど AEStreamWriteDesc と同じです。 リスト 6 の例は、このルーチンの呼び出し方法を示します。

コードの中でネストされたレコードを作成している場合、AEStreamWriteKeyDesc は、最後に行った AEStreamOpenRecord または AEStreamOpenEvent への呼び出しに対応する AERecordAEKeyword/AEDesc のペアを追加します。 AEStreamWriteKeyDesc は、AERecord に対して書き込みが行われている間のみ呼び出せます。AERecord 内でネストされている AEDescList に対して書き込みを行っている間に呼び出して、AERecordAEKeyword/AEDesc のペアを追加することはできません。

先頭に戻る



AEStreamOpenKeyDesc



OSStatus AEStreamOpenKeyDesc(
    AEStreamRef ref,
    AEKeyword key,
    DescType newType);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamOpenKeyDesc を呼び出して、AERecord に含めるキーワード/ディスクリプタのペアの定義を開始します。 AEStreamOpenKeyDesc は、AERecord 要素のキーワードとして使用する AEKeyword を含む以外は AEStreamOpenDesc と同じです。 このルーチンは、AEStreamWriteData を繰り返し呼び出してインクリメンタルに 1 つのキーワード/ディスクリプタに関連するデータを追加する場合に使います。AEStreamOpenKeyDesc の呼出し後は、ディスクリプタのデータ内容を定義するために AEStreamWriteData を何度か呼び出し、その後 AEStreamCloseDesc を呼び出して定義を終えます。

コードの中でネストされたレコードを作成している場合は、最後に行った AEStreamOpenRecord または AEStreamOpenEvent への呼び出しに対応する AERecord において AEKeyword/AEDesc のペアの定義を開始します。 AEStreamOpenKeyDesc は、AERecord に対して書き込みが行われている間のみ呼び出せます。AERecord 内でネストされている AEDescList に対して書き込みを行っている間に呼び出して、AERecordAEKeyword/AEDesc ペアの定義を開始することはできません。

先頭の戻る



AEStreamWriteKey



OSStatus AEStreamWriteKey(
    AEStreamRef ref,
    AEKeyword key);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamWriteKey を呼び出して、AERecord に含めるキーワード/ディスクリプタのペア定義を開始します。このルーチンでは、キーワードの部分の定義のみを書き出し、その後には 1 つのディスクリプタレコードを定義する AEStream* 呼び出しシーケンスが続く必要があります。このディスクリプタは、次のいずれかになります。

リスト 6 の例は、このルーチンの呼び出し方法を示します。

コードの中でネストされたレコードを作成している場合、AEStreamWriteKey は、最後に行った AEStreamOpenRecord または AEStreamOpenEvent への呼び出しと対応する AERecord において AEKeyword/AEDesc のペアの定義を開始します。 AEStreamWriteKey は、AERecord に対して書き込みが行われている間のみ呼び出せます。AERecordAERecord 内でネストされている AEDescList に対して書き込みを行っている間に呼び出して、AEKeyword/AEDesc のペアを開始することはできません。

先頭に戻る



アップルイベントレコードの記述

AEStream* ルーチンを使うことによって、完全なアップルイベントレコードを作成できます。 AEStreamCreateEvent を使えば新しい AppleEvent を定義でき、また AEStreamOpenEvent を使えば既存のレコードを補うことができます。AppleEvent レコードの形式は、 AERecord と同じなので、パラメータの入力には、AERecord の要素の追加に使うのと同じルーチンを使います。アップルイベントの場合には、レコードの書き出しの節で定義されている AEStreamWriteKeyDescAEStreamOpenKeyDesc、または AEStreamWriteKey を使います。AppleEvent レコードでは、省略可能なパラメータも使用できるようになっています。追加したパラメータのどれを省略可能なパラメータにするかを指定できるように、AEStream* には、AEStreamOptionalParam の呼び出しが提供されています。

AEStreamOpenEvent



AEStreamRef AEStreamOpenEvent(AppleEvent *event);

パラメータ:

  • event - パラメータを追加する対象となる既存のアップルイベントレコード。

結果:
AEStreamRef。エラーが発生した場合は、値 NULL



AEStreamOpenEvent により、AEStreamRef にある既存の AppleEvent を開くことができるので、AEStream* ルーチンを使ってパラメータをイベントに追加できるようになります。イベントレコードを開くと、イベントレコードの内容は AEStreamRef にコピーされます。イベントレコードのパラメータを記述し終えたら、AEStreamClose を呼び出し、それらを AppleEvent レコードに保存します。リスト 6 の例は、このルーチンの呼び出し方法を示します。

この操作を完了するのに利用できる十分な空きがない場合、AEStreamOpenEventNULL を返し、AppleEvent パラメータは変更されません。そうでない場合で、操作が無事に完了したときには、 AEStreamOpenEvent は有効な AEStreamRef を返し、AppleEvent パラメータは typeNull のディスクリプタに設定されます。AEStreamOpenEvent を使って AppleEvent レコードを開く時には、この節で説明する AEStreamOptionalParam と一緒に、レコードの書き出しの節で説明した、キーワード/ディスクリプタのペアを追加するために使用するのと同じルーチンを使ってパラメータを指定する必要があります。



リスト 6 AEStreamOpenEvent の呼び出し方法を示す例

AppleEvent event;
AEStreamRef ref;
OSStatus err;
char* p = "Hello World";
....
ref = AEStreamOpenEvent(&event);
if (ref != NULL) {

        /* ダイレクトパラメータを追加 */
    err = AEStreamWriteKeyDesc( ref, keyDirectObject, typeChar, p, strlen(p));
    if (err == noErr) {

            /* 別の省略可能なパラメータを追加 */
        err = AEStreamWriteKey( ref, 'mine');
        if (err == noErr) {

                /* リスト 3 で定義されている AddTextDesc ルーチンを使って、
                すべての文字列をリストに追加
                 */
            err = AddTextDesc( ref, "this is an optional parameter");
            if (err == noErr) {

                    /* キーワード、mine の付いたパラメータを省略可能なパラメータ
                    としてフラグを付ける */
                err = AEStreamOptionalParam( ref, 'mine');
                if (err == noErr) {

                        /* ストリームを閉じる */
                    err = AEStreamClose(ref, &event);
                    if (err == noErr) {

                            /* イベントを送る */
                        err = AESend(&event, ...);
                    ....


AEStreamOpenEvent は、 AppleEventAEStreamRef に読み込んだ後、そこに渡された AppleEvent 構造体の内容をクリアし、 構造体を null ディスクリプタに設定します。 パラメータを書き出した後、AppleEvent をこの変数にコピーし戻すには、AEStreamClose を呼び出し、結果として作成されるディスクリプタレコードの保存先として同じ構造体を 指定します。

先頭に戻る



AEStreamCreateEvent



AEStreamRef AEStreamCreateEvent(
    AEEventClass clazz,
    AEEventID id,
    DescType targetType,
    const void* targetData,
    long targetLength,
    short returnID,
    long transactionID);

パラメータ:

  • clazz - 作成するアップルイベントのイベントクラス。

  • id - 作成するアップルイベントのイベント ID。

  • targetType - 次の 2 つのパラメータに記述されているアドレス情報のアドレスタイプ。通常は、typeApplSignaturetypeProcessSerialNumber、または typeKernelProcessID のどれかです。

  • targetData - アドレス情報へのポインタ。

  • targetLength - targetData パラメータが指すアドレス情報のバイト数。

  • returnID - 通常は、値 kAutoGenerateReturnID に設定されます。詳細については、Apple Event Manager に関する文献を参照してください。

  • transactionID - 通常は、値 kAnyTransactionID に設定されます。 詳細については、Apple Event Manager に関する文献を参照してください。

結果:
AEStreamRef。エラーが発生した場合は、値 NULL



AEStreamCreateEvent は、AEStreamRef を開いてパラメータをイベントに追加するために AEStreamOpenEvent を呼び出す前に、AECreateAppleEvent を呼び出します。

先頭に戻る



AEStreamOptionalParam



OSStatus AEStreamOptionalParam(
    AEStreamRef ref,
    AEKeyword key);

パラメータ:

結果:
呼び出しの成否を数値で表す結果コード。値 noErr(ゼロ)は、呼び出しの成功を意味します。



AEStreamOptionalParam により、AppleEvent における(AEKeywordを使って)省略可能なパラメータを指定できます。リスト 6 は、このルーチンの呼び出し方法を示します。

先頭に戻る



ダウンロード

Acrobat gif

このテクニカルノードの PDF 版

ダウンロード

先頭に戻る